package com.atguigu.bigdata.scala.mytest.chapter07

import scala.io.{BufferedSource, Source}

/**
 * 统计单词出现最多的前三名
 */
object Test_WordCount {
  def main(args: Array[String]): Unit = {
    //将数据读取并存入list
    val source: BufferedSource = Source.fromFile("data/word.txt")
    val lines: Iterator[String] = source.getLines()
    val list: List[String] = lines.toList
    source.close()
    println("源数据:"+list)

    // flatMap就是将集合中的每一个元素获取到，然后进行自定义函数的扁平化操作（拆分）返回list
    val strings: List[String] = list.flatMap((line) => line.split(" "))
    println("flatMap映射处理:"+strings)//flatMap映射处理:List(hello, word, hello, scala, hello, java, hello, word, hello, word, hello, scala, hello, scala, hello, redis, hello, redis, hello, redis, hello, scala)
//    val strings1: List[Array[String]] = list.map(line=>line.split(" "))//map映射处理:List([Ljava.lang.String;@6b2fad11, [Ljava.lang.String;@79698539, [Ljava.lang.String;@73f792cf, [Ljava.lang.String;@2ed94a8b, [Ljava.lang.String;@38082d64, [Ljava.lang.String;@dfd3711, [Ljava.lang.String;@42d3bd8b, [Ljava.lang.String;@26ba2a48, [Ljava.lang.String;@5f2050f6, [Ljava.lang.String;@3b81a1bc)
//    val strings2: List[String] = strings1.flatten(a=>a)//扁平化处理处理:List(hello, word, hello, scala, hello, java, hello, word, hello, word, hello, scala, hello, scala, hello, redis, hello, redis, hello, redis)

    //list按照自定义函数规则分组,list-->map
    //val wordGroup: Map[String, List[String]] = strings.groupBy(word=>word.substring(0,1))//Map(s -> List(scala, scala, scala), j -> List(java), h -> List(hello, hello, hello, hello, hello, hello, hello, hello, hello, hello), r -> List(redis, redis, redis), w -> List(word, word, word))
    val wordGroup: Map[String, List[String]] = strings.groupBy(word=>word)
    println("groupBy按规则分组结果:"+wordGroup)//groupBy按规则分组结果:Map(java -> List(java), scala -> List(scala, scala, scala, scala), redis -> List(redis, redis, redis), hello -> List(hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, hello), word -> List(word, word, word))


    //分组后统计:映射处理每个map的元素t
    val wordCount: Map[String, Int] = wordGroup.map(
      t => {
        val key: String = t._1//获取元素的key  scala
        val values: List[String] = t._2//获取元素的values  List(scala, scala, scala)
        (key, values.size)//作为2元组,即map返回 scala 3
      }
    )
    println("map数量统计:"+wordCount)//map数量统计:Map(java -> 1, scala -> 4, redis -> 3, hello -> 11, word -> 3)

    println("=====================================")
    //统计结果分组
    val wordCountGroupBy: Map[Int, Map[String, Int]] = wordCount.groupBy(p=>p._2)//Map(11 -> Map(hello -> 11), 4 -> Map(scala -> 4), 1 -> Map(java -> 1), 3 -> Map(redis -> 3, word -> 3))
    //分组后处理格式
    val intToStrings: Map[ List[String],Int] = wordCountGroupBy.map(m => {
      val value: Map[String, Int] = m._2
      val list1: List[String] = value.map(m1 => m1._1).toList
      (list1,m._1)
    })
    println("统计结果分组:"+intToStrings)
    //排序
    val list1: List[(List[String], Int)] = intToStrings.toList
    val tuples2: List[(List[String], Int)] = list1.sortBy(w=>w._2)(Ordering.Int.reverse)
    val tuples3: List[(List[String], Int)] = tuples2.take(3)
    println(tuples3)

    println("===========================================")
    //排序取前三个,如果:wordCount为map无法排序,转为list,sortBy默认升序
    val wordCountList: List[(String, Int)] = wordCount.toList//List((java,1), (scala,4), (redis,3), (hello,11), (word,3))
    val tuples: List[(String, Int)] = wordCountList.sortBy(w=>w._2)(Ordering.Int.reverse)
    println("统计结果转list,进行sortBy排序:"+tuples)//转list,进行sortBy排序:List((hello,11), (scala,4), (redis,3), (word,3), (java,1))

    //取前三名
    val tuples1: List[(String, Int)] = tuples.take(3)
    println("取前三个:"+tuples1)//取前三个:List((hello,11), (scala,4), (redis,3))

  }
}
